package cgl.sensorgrid.xml.binary.adapters;

import java.io.*;
import javax.xml.parsers.*;
import javax.xml.transform.*;
import javax.xml.transform.dom.*;
import javax.xml.transform.stream.*;

import org.jvnet.fastinfoset.*;
import org.w3c.dom.*;
import org.xml.sax.*;
import com.sun.xml.fastinfoset.dom.*;
import com.sun.xml.fastinfoset.sax.*;
import com.sun.xml.fastinfoset.stax.*;
import com.sun.xml.fastinfoset.tools.SAX2StAXWriter;
import javax.xml.transform.sax.SAXSource;

/**
 *
 * <p>Title: SensorGrid</p>
 *
 * <p>Description: </p> Test methods for converting to and from Fast Infoset documents.
 *  These methods are taken from FI package
 *
 * <p>Copyright: Copyright (c) 2006</p>
 *
 * <p>Company: </p>
 *
 * @author not attributable
 * @version 1.0
 */

public class FI {

  private SAXParserFactory saxParserFactory;
  private SAXParser saxParser;
  private SAXDocumentSerializer saxDocumentSerializer;

  private StAXDocumentSerializer staxDocumentSerializer;
  private SAX2StAXWriter saxTostax;

  private Transformer tx;

  private static FileWriter fw;

  /**
   *
   *
   */
  public FI() {
    try {
      //sax
      saxParserFactory = SAXParserFactory.newInstance();
      saxParserFactory.setNamespaceAware(true);
      saxParser = saxParserFactory.newSAXParser();
      saxDocumentSerializer = new SAXDocumentSerializer();
      //stax
      staxDocumentSerializer = new StAXDocumentSerializer();
      saxTostax = new SAX2StAXWriter(staxDocumentSerializer);
    }
    catch (SAXException ex) {
    }
    catch (ParserConfigurationException ex) {
    }
    try {
      tx = TransformerFactory.newInstance().
          newTransformer();
    }
    catch (TransformerFactoryConfigurationError ex1) {
    }
    catch (TransformerConfigurationException ex1) {
    }
  }

// XML TO FI

  /**
   *
   * @param xml InputStream
   * @param finf OutputStream
   * @throws Exception
   */
  public void xml_sax_2_fi(InputStream xml, OutputStream finf) throws
          Exception {
      saxParser.setProperty("http://xml.org/sax/properties/lexical-handler",
                            saxDocumentSerializer);
      saxDocumentSerializer.setOutputStream(finf);
      saxParser.parse(xml, saxDocumentSerializer);
  }

  /**
   *
   * @param xml InputStream
   * @param finf OutputStream
   * @throws Exception
   */
  public void xml_sax_stax_2_fi(InputStream xml, OutputStream finf) throws
          Exception {
      saxParser.setProperty("http://xml.org/sax/properties/lexical-handler",
                            saxTostax);
      staxDocumentSerializer.setOutputStream(finf);
      long a = System.nanoTime();
      saxParser.parse(xml, saxTostax);
      xml.close();
      finf.close();
  }

  /**
   *
   * @param document InputStream
   * @param finf OutputStream
   * @throws Exception
   */
  public void xml_dom_2_fi(InputStream document, OutputStream finf) throws
      Exception {
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    dbf.setNamespaceAware(true);
    DocumentBuilder db = dbf.newDocumentBuilder();
    com.sun.xml.fastinfoset.dom.DOMDocumentSerializer s = new com.sun.xml.
            fastinfoset.dom.DOMDocumentSerializer();
    Document d = db.parse(document);
    s.setOutputStream(finf);
    long a = System.nanoTime();
    s.serialize(d);
    fw.write( (System.nanoTime() - a) + "\t");
    System.out.println(System.nanoTime() - a);
  }

  /**
   *
   * @param document InputStream
   * @param finf OutputStream
   * @throws Exception
   */
  public void xml_dom_sax_2_fi(InputStream document, OutputStream finf) throws
      Exception {
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    dbf.setNamespaceAware(true);
    DocumentBuilder db = dbf.newDocumentBuilder();
    Document d = db.parse(document);
    TransformerFactory tf = TransformerFactory.newInstance();
    Transformer t = tf.newTransformer();
    long a = System.nanoTime();
    t.transform(new DOMSource(d), new FastInfosetResult(finf));
    fw.write( (System.nanoTime() - a) + "\t");
    System.out.println(System.nanoTime() - a);
  }

// FI 2 XML

  /**
   *
   * @param fiDocument InputStream
   * @param xmlDocument OutputStream
   */
  public void fi2xml(InputStream fiDocument, OutputStream xmlDocument) {
    try {
        long a = System.nanoTime();
      tx.transform(new FastInfosetSource(fiDocument),
                   new StreamResult(xmlDocument));
    }
    catch (Exception ex) {
      ex.printStackTrace();
    }
  }

public void fi2xml1(InputStream fis, OutputStream out){
    try {
        long a = System.nanoTime();
//        SAXSource ss = new SAXSource(new SAXDocumentParser(), new InputSource(fis));
//        TransformerFactory trf = TransformerFactory.newInstance();
//        Transformer tr = trf.newTransformer();

        TransformerFactory.newInstance().newTransformer().transform(new
                SAXSource(new SAXDocumentParser(), new InputSource(fis)),
                new StreamResult(out));
//        System.out.println(System.nanoTime() - a);
      }
      catch(Exception ex){
          ex.printStackTrace();
      }
}



// XML 2 FI
  /**
   *
   * @param dirPath String
   * @param fw_ FileWriter
   */
  public void xml2fi(String dirPath, FileWriter fw_){
    try {
      this.fw = fw_;
      File f = new File(dirPath);
      if (f.isDirectory()) {
        File[] files = f.listFiles();
        System.out.println("Total " + files.length + " files...");
        for (int i = 0; i < files.length; i++) {
          //get file bytes
          if (files[i].isFile()) {
            DataInputStream dis = new DataInputStream(new
                FileInputStream(files[i]));
            byte[] filebytes = new byte[ (int) files[i].length()];
            dis.readFully(filebytes);

            //convert file
            ByteArrayInputStream bis = new ByteArrayInputStream(
                filebytes);
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            //System.out.print(i + "\t");
            fi2xml(bis, out);
            // System.out.println("");
            byte[] by = out.toByteArray();
            FileOutputStream fos = new FileOutputStream(
                      new File("C:/temp/gml/" +
                               "/xml/" +
                               files[i].getName().substring(0,
                    files[i].getName().indexOf(".") - 1) +
                ".xml"));
            fos.write(by);
          }
        }
      }
      fw.write("\n");
      fw.close();
    }
    catch (Exception ex) {
      ex.printStackTrace();
    }
  }


  ////////////////////// LAST METHODS

  public void fi2xml_jaxp(InputStream bais, OutputStream baos) throws
        Exception {
      SAXDocumentParser s = new SAXDocumentParser();

      SAXSource ss = new SAXSource(s, new InputSource(bais));
      StreamResult sr = new StreamResult(baos);
      //StreamResult sr = new StreamResult(System.out);

      TransformerFactory tf = TransformerFactory.newInstance();
      Transformer t = tf.newTransformer();
      t.transform(ss, sr);
      bais.close();
      baos.close();
    }

    public void parse_fi_sax_xml(InputStream finf, OutputStream xml) throws Exception {
//        Transformer tx = TransformerFactory.newInstance().newTransformer();
        tx.transform(new FastInfosetSource(finf), new StreamResult(xml));
        xml.close();
        finf.close();
    }

    public void parse_xml_sax_fi(InputStream xml, OutputStream finf) throws Exception {
      SAXParser saxParser = saxParserFactory.newSAXParser();
      saxDocumentSerializer = new SAXDocumentSerializer();
      saxDocumentSerializer.setOutputStream(finf);
      saxParser.setProperty("http://xml.org/sax/properties/lexical-handler",
                            saxDocumentSerializer);
      saxParser.parse(xml, saxDocumentSerializer);
    }

  /**
   *
   * @param args String[]
   */
  public static void main(String[] args) {
    try {

        FI fi = new FI();
        args = new String[3];
        args[0] = "C:/projects/XML/gml/gml";
        args[1] = "C:/projects/XML/gml/perf.txt";
        args[2] = "xml";

        String path = args[0];
        String perfPath = args[1];

      FileOutputStream fos = new FileOutputStream(perfPath);

//      for (int k = 0; k < 3; k++) {
          int count = 50;
//      FileOutputStream fos1 = new FileOutputStream("C:/projects/XML/gml/binary/test.txt");

      File f = new File(path);
      File[] fs = f.listFiles();

          for (int i = 0; i < fs.length; i++) {
      //          File f3 = new File("C:/projects/XML/gml/binary/" + count);
      //          f3.mkdir();

              String path2 = path + "/" + count;
              File f2 = new File(path2);
              File[] fs2 = f2.listFiles();
              if (fs2 != null && fs2.length > 0)
                  for (int j = 0; j < fs2.length; j++) {
      //             fos1 = new FileOutputStream("C:/projects/XML/gml/binary/" + count + "/" + j + ".finf");
                      //System.out.println(fs2[j].getCanonicalPath());
                      long a = System.nanoTime();
                      if (args[2].equalsIgnoreCase("fi"))
//                          fi.fi2xml_jaxp(new FileInputStream(fs2[j].getCanonicalPath()),
//                                         new ByteArrayOutputStream());
                          fi.parse_fi_sax_xml(new FileInputStream(fs2[j].getCanonicalPath()),
                                              new ByteArrayOutputStream());
                      if (args[2].equalsIgnoreCase("xml"))
                          fi.xml_sax_2_fi(new FileInputStream(fs2[j].getCanonicalPath()),
                                          new ByteArrayOutputStream());
                      long b = System.nanoTime();
                      String time = (b - a) + "\n";
                      fos.write(time.getBytes());
                      //System.out.println((b-a));
                  }
              System.out.println(count);
              count += 50;
              fos.write("\n\n".getBytes());
          }
//          fos.close();
//      }
//
//      fi.fi2xml(new FileInputStream("C:/temp/gml/fi/114529787385.xml"),
//                new FileOutputStream("C:/temp/gml/DEMO1.xml"));
//
//      System.out.println("FI2XML 1");
//      for (int j = 0; j < 5; j++) {
//          ByteArrayOutputStream bos = new ByteArrayOutputStream();
//          FileOutputStream fos = new FileOutputStream("C:/temp/gml/DEMO1.xml");
//          FileInputStream fis = new FileInputStream(
//                  "C:/temp/gml/fi/114529787385.xml");
//          System.out.println("\nFI2XML 2");
//          for (int i = 0; i < 10; i++) {
//              fis = new FileInputStream("C:/temp/gml/fi/114529787385.xml");
//              bos = new ByteArrayOutputStream();
//              fi.fi2xml1(fis, bos);
//          }
//      }
    }
    catch (Exception ex) {
      ex.printStackTrace();
    }
  }
}
